package com.google.denta.aspect;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.ui.Model;
import org.springframework.util.StopWatch;
import org.springframework.validation.BindingResult;

import com.google.denta.spring.mvc.user.UserForm;

/**
 * Benchmark.
 */
@Aspect
public class UserBenchmarkAspect {
    /** Logger. */
    private final Logger logger = Logger.getLogger(this.getClass());

    /**
     * Pointcut handle.
     * @param form
     *            UserForm
     * @param result
     *            BindingResult aspect system
     * @param model
     *            Model aspect system
     */
    @Pointcut("execution(* com.google.denta.spring.mvc.user.UserControler.update(..))"
            + " && args(form, result, model)")
    public void profile(final UserForm form, final BindingResult result,
            final Model model) {
    }

    /**
     * Pointcut handle around action.
     * @param jp
     *            ProceedingJoinPoint aspect system
     * @param form
     *            UserForm
     * @param result
     *            BindingResult aspect system
     * @param model
     *            Model aspect system
     * @return Object aspect system
     * @throws Throwable exeption
     */
    @Around("profile(form, result, model)")
    public Object execute(final ProceedingJoinPoint jp, final UserForm form,
            final BindingResult result, final Model model) throws Throwable {
        final StopWatch sw = new StopWatch(jp.toShortString());
        try {
            sw.start(jp.toShortString());
            return jp.proceed();
        } finally {
            sw.stop();
            if (jp.getSignature() instanceof MethodSignature) {
                final StringBuilder sb = new StringBuilder("!!!!!!!!!!!!!!!\'");
                sb.append(((MethodSignature) jp.getSignature()).getMethod()
                        .toGenericString());
                sb.append('\'');
                sb.append(" : running time (millis) = ");
                sb.append(sw.getTotalTimeMillis());
                logger.debug(sb.toString());
            } else {
                logger.debug(sw.shortSummary());
            }
        }
    }
}
